<template>
  <!-- 外层容器解决多根节点问题 -->
  <span class="button-wrapper">
    <!-- 带工具提示的按钮 -->
    <el-tooltip
        v-if="tooltipContent"
        :content="tooltipContent"
        :placement="tooltipPlacement"
        :effect="tooltipEffect"
    >
      <el-button
          v-bind="$attrs"
          :loading="async ? isLoading : false"
          :class="['custom-button']"
          @click="handleClick"
      >
        <template #icon>
          <slot name="icon">
            <i v-if="icon" :class="`el-icon-${icon}`"></i>
          </slot>
        </template>
        <template #loading>
          <slot name="loading"></slot>
        </template>
        <slot name="left-text"></slot>
        <slot name="prefixIcon">
          <i v-if="icon" :class="`el-icon-${icon}`"></i>
          <i v-if="prefixIcon" :class="prefixIcon"></i>
        </slot>
        <slot></slot>
        <slot name="suffixIcon">
          <i v-if="suffixIcon" :class="suffixIcon"></i>
        </slot>
        <slot name="right-icon"></slot>
      </el-button>
    </el-tooltip>

    <!-- 普通按钮 -->
    <el-button
        v-else
        v-bind="$attrs"
        :loading="async ? isLoading : false"
        :class="['custom-button']"
        @click="handleClick"
    >
      <!-- 重复插槽内容 -->
      <template #icon>
        <slot name="icon">
          <i v-if="icon" :class="`el-icon-${icon}`"></i>
        </slot>
      </template>
      <template #loading>
        <slot name="loading"></slot>
      </template>
      <slot name="left-text"></slot>
      <slot name="prefixIcon">
        <i v-if="icon" :class="`el-icon-${icon}`"></i>
        <i v-if="prefixIcon" :class="prefixIcon"></i>
      </slot>
      <slot></slot>
      <slot name="suffixIcon">
        <i v-if="suffixIcon" :class="suffixIcon"></i>
      </slot>
      <slot name="right-icon"></slot>
    </el-button>
  </span>
</template>

<script>
export default {
  name: 'ElButtonPlus',
  inheritAttrs: false,

  props: {
    // 新增工具提示相关属性
    /**
     * @type {String}
     * @desc 工具提示内容
     * @default ''
     */
    tooltipContent: {
      type: String,
      default: ''
    },
    /**
     * @type {String}
     * @desc 提示框位置，可选值：top/bottom/left/right
     * @default 'bottom'
     */
    tooltipPlacement: {
      type: String,
      default: 'bottom'
    },
    /**
     * @type {String}
     * @desc 提示框样式效果
     * @default 'dark'
     */
    tooltipEffect: {
      type: String,
      default: 'dark'
    },

    // 原有属性
    /**
     * @type {Boolean}
     * @desc 是否启用异步点击处理
     * @default false
     */
    async: {
      type: Boolean,
      default: false
    },
    /**
     * @type {String}
     * @desc 前缀图标类名
     */
    prefixIcon: String,
    /**
     * @type {String}
     * @desc 后缀图标类名
     */
    suffixIcon: String,
    /**
     * @type {Number}
     * @desc 节流等待时间(毫秒)
     * @default 0
     */
    throttleWait: {
      type: Number,
      default: 0
    },
    /**
     * @type {Number}
     * @desc 防抖等待时间(毫秒)
     * @default 0
     */
    debounceWait: {
      type: Number,
      default: 0
    },
    /**
     * @type {String}
     * @desc 图标名称(带el-icon-前缀)
     */
    icon: String,
  },


  data() {
    return {
      lastExecTime: 0,
      timer: null,
      isLoading: false
    };
  },
  methods: {
    _emitClick(e) {
      this.$emit('click', e);
    },

    debounceHandler(e) {
      clearTimeout(this.timer);
      this.timer = setTimeout(() => this.$emit('async-click', {
        event: e,
        done: () => this.isLoading = false
      }), this.debounceWait);
    },

    throttleHandler(e) {
      const now = Date.now();
      if (now - this.lastExecTime >= this.throttleWait) {
        this.$emit('async-click', {
          event: e,
          done: () => this.isLoading = false
        });
        this.lastExecTime = now;
      }
    },

    handleClick(e) {
      if (this.async) {
        this.isLoading = true;
        if (this.debounceWait > 0) {
          this.debounceHandler(e);
        } else if (this.throttleWait > 0) {
          this.throttleHandler(e);
        } else {
          this.$emit('async-click', {
            event: e,
            done: () => this.isLoading = false
          });
        }
      } else {
        this._emitClick(e);
      }
    },
  },

  beforeDestroy() {
    clearTimeout(this.timer);
  }
};
</script>

<style lang="less" scoped>
.custom-button {
  margin-left: 0 !important;
  position: relative;
  overflow: hidden;
}

.button-wrapper {
  display: inline-block;

  .custom-button {
    margin-left: 0 !important;
  }

  /* 解决tooltip包裹时的行内样式问题 */

  :deep(.el-tooltip) {
    vertical-align: top;
  }
}

:deep(.el-button) {
  position: relative;
  overflow: hidden !important;
}
</style>